package cn.easyplatform.studio.dao.impl;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.dao.DaoException;
import cn.easyplatform.studio.dao.DaoUtils;
import cn.easyplatform.studio.dao.Dialect;
import cn.easyplatform.studio.dao.TaskLinkDao;
import cn.easyplatform.studio.dao.transaction.JdbcTransactions;
import cn.easyplatform.studio.vos.TypeLinkVo;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class AbstractTaskLinkDao implements TaskLinkDao {
    private DataSource ds;

    public AbstractTaskLinkDao(DataSource dataSource) {
        this.ds = dataSource;
    }

    protected abstract Dialect getDialect();
    @Override
    public List<TypeLinkVo> getAllTaskLink(String linkTable, String taskLinkTable) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select " + taskLinkTable + ".entityId,"+ taskLinkTable
                    + ".childrenEntityId,entityName,entityType,entitySubType,entityDesp,updateDate,updateUser,"
                    + taskLinkTable + ".isRoot,status from " + linkTable + "," + taskLinkTable + " where "
                    + linkTable + ".entityId=" + taskLinkTable + ".entityId");
            rs = pstmt.executeQuery();
            List<TypeLinkVo> list = new ArrayList<TypeLinkVo>();
            while (rs.next()) {
                TypeLinkVo vo = new TypeLinkVo(rs.getString(1),rs.getString(2),
                        rs.getString(3),rs.getString(4),rs.getString(5),
                        rs.getString(6),rs.getDate(7),rs.getString(8),
                        rs.getString(9),rs.getString(10));
                list.add(vo);
            }
            return list;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public TypeLinkVo getTaskLink(String linkTable, String taskLinkTable, String entityId) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select " + taskLinkTable + ".entityId,"+ taskLinkTable
                    + ".childrenEntityId,entityName,entityType,entitySubType,entityDesp,updateDate,updateUser,"
                    + taskLinkTable + ".isRoot,status from " + linkTable + "," + taskLinkTable + " where "
                    + linkTable + ".entityId=" + taskLinkTable + ".entityId"
                    + " AND " + linkTable + ".entityId=?");
            pstmt.setString(1, entityId);
            rs = pstmt.executeQuery();
            TypeLinkVo vo = null;
            while (rs.next()) {
                vo = new TypeLinkVo(rs.getString(1),rs.getString(2),
                        rs.getString(3),rs.getString(4),rs.getString(5),
                        rs.getString(6),rs.getDate(7),
                        rs.getString(8),rs.getString(9),rs.getString(10));
            }
            return vo;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public boolean deleteTaskLink(String taskLinkTable, String entityId)
    {
        if (Strings.isBlank(entityId))
        {
            return false;
        }
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            conn = JdbcTransactions.getConnection(ds);
            pstmt = conn
                    .prepareStatement("delete from " + taskLinkTable +
                            " where 1=1 and entityId=?");
            pstmt.setString(1, entityId);
            pstmt.executeUpdate();
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt);
        }
        return true;
    }

    @Override
    public boolean updateTaskLink(String taskLinkTable, TypeLinkVo vo)
    {
        if (vo == null)
        {
            return false;
        }
        synchronized (vo){
            PreparedStatement pstmt = null;
            Connection conn = null;
            try {
                conn = JdbcTransactions.getConnection(ds);
                pstmt = conn.prepareStatement("UPDATE " + taskLinkTable + " SET isRoot=?,childrenEntityId=? " +
                        "WHERE entityId=? ");
                pstmt.setString(1, vo.isRoot());
                pstmt.setString(2, vo.getChildrenEntityId());
                pstmt.setString(3, vo.getEntityId());
                pstmt.execute();
                pstmt.close();
            } catch (SQLException ex) {
                throw new DaoException(ex.getMessage());
            } finally {
                DaoUtils.closeQuietly(pstmt);
            }
        }
        return true;
    }

    @Override
    public boolean addTaskLink(String taskLinkTable, TypeLinkVo vo)
    {
        if (vo == null)
        {
            return false;
        }
        synchronized (vo){
            PreparedStatement pstmt = null;
            Connection conn = null;
            try {
                conn = JdbcTransactions.getConnection(ds);
                pstmt = conn
                        .prepareStatement("insert into " + taskLinkTable +
                                " (`entityId`, `childrenEntityId`, `isRoot`) " +
                                "values(?,?,?)");
                pstmt.setString(1, vo.getEntityId());
                pstmt.setString(2, vo.getChildrenEntityId());
                pstmt.setString(3, vo.isRoot());
                pstmt.executeUpdate();
            } catch (SQLException ex) {
                throw new DaoException(ex.getMessage());
            } finally {
                DaoUtils.closeQuietly(pstmt);
            }
        }
        return true;
    }

    @Override
    public List<TypeLinkVo> getLinkWithChildrenEntityId(String linkTable, String taskLinkTable, String entityId) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            Connection conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("select " + taskLinkTable + ".entityId," + taskLinkTable
                    + ".childrenEntityId,entityName,entityType,entitySubType,entityDesp,updateDate,updateUser,"
                    + taskLinkTable + ".isRoot,status from " + linkTable + "," + taskLinkTable
                    + " where " + linkTable + ".entityId=" + taskLinkTable + ".entityId AND "
                    + taskLinkTable + ".entityId LIKE '%" + entityId + "%'");
            rs = pstmt.executeQuery();
            List<TypeLinkVo> list = new ArrayList<>();
            while (rs.next()) {
                TypeLinkVo vo = new TypeLinkVo(rs.getString(1),rs.getString(2),
                        rs.getString(3),rs.getString(4),rs.getString(5),
                        rs.getString(6),rs.getDate(7),
                        rs.getString(8),rs.getString(9),rs.getString(10));
                list.add(vo);
            }
            return list;
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt, rs);
        }
    }

    @Override
    public boolean updateTaskLinks(String taskLinkTable, List<TypeLinkVo> voList) {
        if (voList == null || voList.size() == 0)
        {
            return false;
        }
        PreparedStatement pstmt = null;
        Connection conn = null;
        try {
            conn = JdbcTransactions.getConnection(ds);
            pstmt = conn.prepareStatement("UPDATE " + taskLinkTable +
                    " SET childrenEntityId=?,isRoot=?" +
                    "WHERE entityId=?");
            for (TypeLinkVo vo : voList) {
                pstmt.setString(1, vo.getChildrenEntityId());
                pstmt.setString(2, vo.isRoot());
                pstmt.setString(3, vo.getEntityId());
                pstmt.addBatch();
            }
            pstmt.executeBatch();
        } catch (SQLException ex) {
            throw new DaoException(ex.getMessage());
        } finally {
            DaoUtils.closeQuietly(pstmt);
        }
        return true;
    }
}
